/**
 * stateController
 *
 * @file 状态控制器（状态模式）
 * */

/**
 * StateController - 状态控制器
 *
 * @class
 * @extends Object
 * */
export const StateController = function () {
    return {
        /**
         * stateKey - 选中状态对象键名
         *
         * @type String
         * */
        stateKey: '',
        /**
         * stateObj - 选中状态对象
         *
         * @type any
         * @memberOf StateController
         * */
        stateObj: {},
        /**
         * statePool - 状态池
         *
         * @type Object
         * @memberOf StateController
         * */
        statePool: {},
        /**
         * hasState - 状态池是否存在指定状态对象
         *
         * @function
         * @param { any } stateKey - 状态对象键名
         * @return { boolean } 状态池是否存在指定状态对象
         * @memberOf StateController
         * */
        hasState: function (stateKey) {
            return this.statePool[stateKey] !== void 0;
        },
        /**
         * addState - 向状态池注册新状态对象
         *
         * @function
         * @param { any } newStateKey - 新状态对象键名
         * @param { any } newStateObj - 新状态对象
         * @param { boolean } [strict = true] - 严格模式，默认开启, 开启则遇到重复状态对象则报错，关闭则覆盖
         * @return { Object } 添加的状态对象
         * @throws { RangeError } - 已存在指定状态对象，请勿重复添加！
         * @memberOf StateController
         * */
        addState: function (newStateKey, newStateObj, strict = true) {
            if (this.hasState(newStateKey) && strict) {
                throw new RangeError('已存在指定状态对象，请勿重复添加！');
            }

            this.statePool[newStateKey] = newStateObj;

            return {
                key: newStateKey,
                value: newStateObj
            };
        },
        /**
         * removeState - 状态池移除指定状态对象
         *
         * @function
         * @param { any } stateKey - 状态对象键名
         * @param { boolean } [strict = true] - 严格模式，默认开启, 开启时不存在状态对象则抛出错误，关闭则忽略
         * @return { Object|undefined } 移除的状态对象（若存在）或空（非严格模式未找到指定状态对象）
         * @throws { ReferenceError } - 未找到指定状态对象！
         * @memberOf StateController
         * */
        removeState: function (stateKey, strict = true) {
            if (this.hasState(stateKey)) {
                const removeStateObj = this.statePool[stateKey];

                delete this.statePool[stateKey];

                return removeStateObj;
            }

            if (strict) {
                throw new ReferenceError('未找到指定状态对象！');
            }
        },
        /**
         * updateState - 更新状态池中指定状态对象
         *
         * @function
         * @param { any } stateKey - 状态对象键名
         * @param { any } stateObj - 新状态对象
         * @param { boolean } [strict = true] - 严格模式，默认开启, 开启时不存在状态对象则抛出错误，关闭则忽略
         * @throws { ReferenceError } - 未找到指定状态对象！
         * @memberOf StateController
         * */
        updateState: function (stateKey, stateObj, strict = true) {
            if (this.hasState(stateKey)) {
                this.statePool[stateKey] = stateObj;

                return;
            }

            if (strict) {
                throw new ReferenceError('未找到指定状态对象！');
            }
        },
        /**
         * changeState - 改变状态至指定状态
         *
         * @function
         * @param { any } stateKey - 需要更改成状态对象键名
         * @param { boolean } [strict = true] - 严格模式，默认开启, 开启时不存在状态对象则抛出错误，关闭则忽略
         * @throws { ReferenceError } - 状态池中不存在指定状态对象！
         * @memberOf StateController
         * */
        changeState: function (stateKey, strict = true) {
            if (this.hasState(stateKey)) {
                this.stateKey = stateKey;
                this.stateObj = this.statePool[stateKey];

                return;
            }

            if (strict) {
                throw new ReferenceError('状态池中不存在指定状态对象！');
            }
        }
    }
}

export default StateController
